#include "history.h"
#include "ui_history.h"


History::History(QWidget* parent) :
    QWidget(parent),
    ui(new Ui::history)
{
    ui->setupUi(this);
    initChart();
    initChannel();
    initTableView();
    initAlarmView();
    connect(this, &History::recPageChanged, [ = ]()
    {
        ui->RecPageFrist->setEnabled(true);
        ui->RecPagePrevious->setEnabled(true);
        ui->RecPageNext->setEnabled(true);
        ui->RecPageEnd->setEnabled(true);

        if(recPage == 1)
        {
            ui->RecPageFrist->setEnabled(false);
            ui->RecPagePrevious->setEnabled(false);
        }

        if(recPage >= recPages)
        {
            ui->RecPageNext->setEnabled(false);
            ui->RecPageEnd->setEnabled(false);
        }
    });
    connect(this, &History::alarmPageChanged, [ = ]()
    {
        ui->AlarmPageFrist->setEnabled(true);
        ui->AlarmPagePrevious->setEnabled(true);
        ui->AlarmPageNext->setEnabled(true);
        ui->AlarmPageEnd->setEnabled(true);

        if(alarmPage == 1)
        {
            ui->AlarmPageFrist->setEnabled(false);
            ui->AlarmPagePrevious->setEnabled(false);
        }

        if(alarmPage >= alarmPages)
        {
            ui->AlarmPageNext->setEnabled(false);
            ui->AlarmPageEnd->setEnabled(false);
        }
    });
}

void History::initAlarmView()
{
    alarmmodel = new QSqlQueryModel(this);
    alarmmodel->setQuery("select datetime(numtime, 'unixepoch', 'localtime'), chname, numvalue from alarm order by numtime desc");
    alarmmodel->setHeaderData(0, Qt::Horizontal, tr("时间"));
    alarmmodel->setHeaderData(1, Qt::Horizontal, tr("卡槽号"));
    alarmmodel->setHeaderData(2, Qt::Horizontal, tr("事件内容"));
    QSortFilterProxyModel* sqlproxyA = new QSortFilterProxyModel(this);
    sqlproxyA->setSourceModel(alarmmodel);
    ui->tableViewAlarm->setModel(sqlproxyA);
    ui->tableViewAlarm->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->tableViewAlarm->setColumnWidth(0, 200);
    ui->tableViewAlarm->setColumnWidth(1, 150);
    ui->tableViewAlarm->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
}

void History::initTableView()
{
    model = new QSqlQueryModel(this);
    model->setQuery("select chname, datetime(numtime, 'unixepoch', 'localtime'), value, unit "
                    "from concentration "
                    "where chname like 'CHA1 %' "
                    "order by numtime desc "
                    "limit 0, 20");
    model->setHeaderData(0, Qt::Horizontal, tr("卡槽号"));
    model->setHeaderData(1, Qt::Horizontal, tr("日期"));
    model->setHeaderData(2, Qt::Horizontal, tr("数值"));
    model->setHeaderData(3, Qt::Horizontal, tr("单位"));
    QSortFilterProxyModel* sqlproxy = new QSortFilterProxyModel(this);
    sqlproxy->setSourceModel(model);
    ui->recordTableView->setModel(sqlproxy);
    ui->recordTableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->recordTableView->setColumnWidth(0, 150);
    ui->recordTableView->setColumnWidth(1, 200);
    ui->recordTableView->setColumnWidth(2, 150);
    ui->recordTableView->setColumnWidth(3, 100);
}

void History::initChannel()
{
    QSettings configIni(QCoreApplication::applicationDirPath() + "/config.ini", QSettings::IniFormat);
    QListWidgetItem* item;
    ui->channelListWidget->clear();
    ui->channelListWidgetA->clear();
    item = new QListWidgetItem();
    item->setText(tr("显示全部"));
    item->setIcon(QIcon(":/image/all.png"));
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
    ui->channelListWidgetA->addItem(item);

    for(int i = 1; i <= MAX_CARD_COUNT; i++)
    {
        configIni.beginGroup("msa");
        QString chaname = configIni.value(QString("a%1").arg(i), tr("未使用")).toString();
        QString chbname = configIni.value(QString("b%1").arg(i), tr("未使用")).toString();
        configIni.endGroup();
        item = new QListWidgetItem();
        item->setText(QString("CHA%1 %2").arg(i).arg(chaname));
        item->setIcon(QIcon(":/image/A.png"));
        item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
        ui->channelListWidget->addItem(item);
        item = new QListWidgetItem();
        item->setText(QString("CHA%1 %2").arg(i).arg(chaname));
        item->setIcon(QIcon(":/image/A.png"));
        item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
        ui->channelListWidgetA->addItem(item);
        item = new QListWidgetItem();
        item->setText(QString("CHB%1 %2").arg(i).arg(chbname));
        item->setIcon(QIcon(":/image/B.png"));
        item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
        ui->channelListWidget->addItem(item);
        item = new QListWidgetItem();
        item->setText(QString("CHB%1 %2").arg(i).arg(chbname));
        item->setIcon(QIcon(":/image/B.png"));
        item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
        ui->channelListWidgetA->addItem(item);
    }

    connect(ui->channelListWidget, SIGNAL(clicked(QModelIndex)), this, SLOT(itemClicked(QModelIndex)));
    connect(ui->channelListWidgetA, SIGNAL(clicked(QModelIndex)), this,
            SLOT(alarmClicked(QModelIndex)));
}

void History::alarmClicked(QModelIndex index)
{
    // 获取通道名
    QString strTemp, sqlcmd;
    strTemp = index.data().toString();
    int i = strTemp.indexOf(' ');
    strTemp = strTemp.left(i);

    // 计算页面
    if(index.row() == 0)
    {
        sqlcmd = QString("select count(*) from alarm");
    }
    else
    {
        sqlcmd = QString("select count(*) from alarm where chname like '%1 %'").arg(strTemp);
    }

    QSqlQuery query;
    query.exec(sqlcmd);
    query.next();
    int recs = query.value(0).toInt();

    if(recs % alarmSize != 0)
    {
        alarmPages = recs / alarmSize + 1;
    }
    else
    {
        alarmPages = recs / alarmSize;
    }

    alarmPage = 1;
    alarmChannelIndex = index;  // 保存当前通道号
    showAlarm(index);
    emit alarmPageChanged();
    //qDebug() << recs << alarmPage << alarmPages;
    //qDebug() << alarmChannelIndex;
}

void History::showAlarm(QModelIndex index)
{
    QString sqlcmd;
    QString ppp = tr("第 %1/%2 页。每页记录").arg(alarmPage).arg(alarmPages);
    ui->alarmPage->setText(ppp);
    QString strTemp, strTempSql;
    strTemp = index.data().toString();
    int i = strTemp.indexOf(' ');
    strTemp = strTemp.left(i);

    if(index.row() == 0)
        sqlcmd = QString("select datetime(numtime, 'unixepoch', 'localtime'), chname, numvalue "
                         "from alarm order by numtime desc "
                         "limit %1, %2").arg(alarmSize * (alarmPage - 1)).arg(alarmSize);
    else
        sqlcmd = QString("select datetime(numtime, 'unixepoch', 'localtime'), chname, numvalue "
                         "from alarm  where chname like '%1 %' order by numtime desc "
                         "limit %2, %3").arg(strTemp).arg(alarmSize * (alarmPage - 1)).arg(alarmSize);

    alarmmodel->setQuery(sqlcmd);
    //qDebug() << index.row() << sqlcmd;
}

void History::itemClicked(QModelIndex index)
{
    // 获取通道名
    QString strTemp, strTempSql;
    strTemp = index.data().toString();
    int i = strTemp.indexOf(' ');
    strTemp = strTemp.left(i);

    if(ui->nonZero->isChecked())
    {
        strTempSql = "and value<>0 ";
    }
    else
    {
        strTempSql = " ";
    }

    // 计算页面
    QString sqlcmd = QString("select count(*) from concentration "
                             "where chname like '%1 %' %2").arg(strTemp).arg(strTempSql);
    QSqlQuery query;
    query.exec(sqlcmd);
    query.next();
    int recs = query.value(0).toInt();

    if(recs % recSize != 0)
    {
        recPages = recs / recSize + 1;
    }
    else
    {
        recPages = recs / recSize;
    }

    recPage = 1;
    recChannelIndex = index;  // 保存当前通道号
    showRecord(index);
    emit recPageChanged();
    // qDebug() << recs << recPage << recPages;
}

// 将数据显示在表中，并显示曲线
void History::showRecord(QModelIndex index)
{
    double minValue = 0, maxValue = 0, tempD;
    QDateTime maxT, minT, tempT;
    QList<QPointF> xyPoint;
    QString ppp = tr("第 %1/%2 页。每页记录").arg(recPage).arg(recPages);
    ui->recordPage->setText(ppp);
    QString strTemp, strTempSql;
    strTemp = index.data().toString();
    int i = strTemp.indexOf(' ');
    strTemp = strTemp.left(i);

    if(ui->nonZero->isChecked())
    {
        strTempSql = "and value<>0 ";
    }
    else
    {
        strTempSql = " ";
    }

    QString sqlcmd =
    QString("select chname, datetime(numtime, 'unixepoch', 'localtime'), value, unit, numtime "
            "from concentration where chname like '%1 %' %2 "
            "order by numtime desc "
            "limit %3, %4").arg(strTemp).arg(strTempSql).arg(recSize * (recPage - 1)).arg(recSize);
    model->setQuery(sqlcmd);
    model->setHeaderData(0, Qt::Horizontal, tr("卡槽号"));
    model->setHeaderData(1, Qt::Horizontal, tr("日期"));
    model->setHeaderData(2, Qt::Horizontal, tr("数值"));
    model->setHeaderData(3, Qt::Horizontal, tr("单位"));
    ui->recordTableView->hideColumn(4);
    QSqlRecord record;

    while(model->canFetchMore())
    {
        model->fetchMore();
    }

    chart->setTitle(tr("%1历史曲线").arg(strTemp));
    int rc = model->rowCount();

    if(rc == 0)
    {
        series->clear();
        return;
    }

    // 第一条记录
    record = model->record(0);
    maxT = QDateTime::fromSecsSinceEpoch(record.value("numtime").toLongLong());
    // 最后一条记录
    record = model->record(rc - 1);
    minT = QDateTime::fromSecsSinceEpoch(record.value("numtime").toLongLong());
    //qDebug() << rc << (maxT) << (minT);
    axisX->setRange(minT, maxT);

    for(int i = 0; i < rc; i++)
    {
        record = model->record(i);
        tempT = QDateTime::fromSecsSinceEpoch(record.value("numtime").toLongLong());
        tempD = record.value("value").toDouble();
        xyPoint.append(QPointF(tempT.toMSecsSinceEpoch(), tempD));
        //qDebug() << tempT << tempD;
        minValue = minValue > tempD ? tempD : minValue;
        maxValue = maxValue < tempD ? tempD : maxValue;
        //QCoreApplication::processEvents();
    }

    axisY->setRange(minValue - 5, maxValue + 5);
    series->replace(xyPoint);
    //qDebug() << minValue << maxValue;
}

void History::initChart()
{
    QPen blue(Qt::blue);
    blue.setWidth(2);
    series = new QLineSeries();
    series->setPen(blue);
    series->setUseOpenGL(true);
    chart = new QChart();
    chart->addSeries(series);
    chart->legend()->hide();
    chart->setTitleFont(QFont("", 14));
    chart->setTitle("历史曲线");
    axisX = new QDateTimeAxis();
    axisX->setFormat("MM-dd hh:mm");
    axisX->setTitleText("时间");
    chart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);
    axisY = new QtCharts::QValueAxis();
    axisY->setLabelFormat("%i");
    axisY->setTitleText("浓度");
    chart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);
    connect(series, &QLineSeries::hovered, this, [ = ](const QPointF & point,
                                                       bool state)//用于鼠标移动到点上显示数值
    {
        if(state)
        {
            ui->serieslabel->setText(QString::asprintf("%1.0f", point.y()));
            QPoint curPos = ui->chartFrame->mapFromGlobal(QCursor::pos());
            ui->serieslabel->move(curPos.x() + 30 - ui->serieslabel->width() / 2,
                                  curPos.y() + 10 - ui->serieslabel->height() * 1.5); //移动数值
            ui->serieslabel->show();//显示出来
        }
        else
        {
            ui->serieslabel->hide();    //进行隐藏
        }
    });
    //把chart显示到窗口上
    ui->chartFrame->setChart(chart);
    ui->chartFrame->setRenderHint(QPainter::Antialiasing); //设置抗锯齿
    ui->chartFrame->setMouseTracking(true);
}

History::~History()
{
    delete ui;
}

void History::on_btnClose_clicked()
{
    close();
}

void History::on_RecPageFrist_clicked()
{
    if(recPage > 1)
    {
        recPage = 1;
        showRecord(recChannelIndex);
    }

    emit recPageChanged();
}

void History::on_RecPagePrevious_clicked()
{
    if(recPage > 1)
    {
        recPage--;
        showRecord(recChannelIndex);
    }

    emit recPageChanged();
}

void History::on_RecPageNext_clicked()
{
    if(recPage < recPages)
    {
        recPage++;
        showRecord(recChannelIndex);
    }

    emit recPageChanged();
}

void History::on_RecPageEnd_clicked()
{
    if(recPage < recPages)
    {
        recPage = recPages;
        showRecord(recChannelIndex);
    }

    emit recPageChanged();
}

void History::on_cBoxRecord_currentIndexChanged(int index)
{
    recSize = (ui->cBoxRecord->itemText(index)).toInt();
    //qDebug() << ui->cBoxRecord->itemText(index);
}

void History::on_cBoxAlarm_currentIndexChanged(int index)
{
    alarmSize = (ui->cBoxAlarm->itemText(index)).toInt();
}

void History::on_AlarmPageFrist_clicked()
{
    if(alarmPage > 1)
    {
        alarmPage = 1;
        showAlarm(alarmChannelIndex);
    }

    emit alarmPageChanged();
}

void History::on_AlarmPagePrevious_clicked()
{
    if(alarmPage > 1)
    {
        alarmPage--;
        showAlarm(alarmChannelIndex);
    }

    emit alarmPageChanged();
}

void History::on_AlarmPageNext_clicked()
{
    if(alarmPage < alarmPages)
    {
        alarmPage++;
        showAlarm(alarmChannelIndex);
    }

    emit alarmPageChanged();
}

void History::on_AlarmPageEnd_clicked()
{
    if(alarmPage < alarmPages)
    {
        alarmPage = alarmPages;
        showAlarm(alarmChannelIndex);
    }

    emit alarmPageChanged();
}
